#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
LVGL Guiguider Project Porting Script
This script ports an LVGL Guiguider project from v8.3.0 to v9.2.1.

Usage:
    python port_guiguider.py <input_file.guiguider> [output_file.guiguider]

If output_file is not specified, it defaults to <input_name>_port.guiguider
"""

import json
import sys
import os


def load_guiguider_file(file_path):
    """Load a .guiguider file and return its JSON content."""
    try:
        with open(file_path, "r", encoding="utf-8") as f:
            return json.load(f)
    except FileNotFoundError:
        print(f"Error: File '{file_path}' not found.")
        sys.exit(1)
    except json.JSONDecodeError as e:
        print(f"Error: Failed to decode JSON from '{file_path}': {e}")
        sys.exit(1)


def save_guiguider_file(data, file_path):
    """Save JSON data to a .guiguider file."""
    try:
        # 准备输出参数以匹配sort_json.py脚本
        output_kwargs = {"indent": 2, "ensure_ascii": False, "separators": (",", ": ")}

        with open(file_path, "w", encoding="utf-8") as f:
            json.dump(data, f, **output_kwargs)
        print(f"Successfully saved to '{file_path}'")
    except Exception as e:
        print(f"Error: Failed to save file '{file_path}': {e}")
        sys.exit(1)


def port_project(input_file, output_file, reference_file):
    """Port an LVGL Guiguider project from v8.3.0 to v9.2.1."""
    # Load the reference v9.2.1 project
    v9_project = load_guiguider_file(reference_file)

    # Load the input v8.3.0 project
    v8_project = load_guiguider_file(input_file)

    # Extract non-FrontJson content from v9.2.1 project
    v9_non_frontjson = {
        key: value for key, value in v9_project.items() if key != "FrontJson"
    }

    # Extract FrontJson content from v8.3.0 project
    v8_frontjson = v8_project.get("FrontJson", [])

    # Create the ported project by combining v9 non-FrontJson content with v8 FrontJson content
    ported_project = v9_non_frontjson.copy()
    ported_project["FrontJson"] = v8_frontjson

    # Apply specific conversions for v8 to v9 differences
    ported_project = apply_v8_to_v9_conversions(ported_project)

    # Save the ported project
    save_guiguider_file(ported_project, output_file)


def apply_v8_to_v9_conversions(project):
    """Apply specific conversions for v8 to v9 differences."""
    # Update project version information
    project["version"] = "1.9.1-GA"
    project["lvglVersion"] = "v9"

    # Update boardPlatformSettings
    if "boardPlatformSettings" in project:
        project["boardPlatformSettings"]["lvgl_version_major"] = 9
        project["boardPlatformSettings"]["lvgl_version_minor"] = 2
        project["boardPlatformSettings"]["lvgl_version_micro"] = 1
        project["boardPlatformSettings"]["uid"] = project["boardPlatformSettings"][
            "uid"
        ].replace("v8", "v9")

    # Update demoTemplateSettings
    if "demoTemplateSettings" in project:
        project["demoTemplateSettings"]["lvgl_version_major"] = 9
        project["demoTemplateSettings"]["lvgl_version_minor"] = 2
        project["demoTemplateSettings"]["lvgl_version_micro"] = 1
        project["demoTemplateSettings"]["uid"] = project["demoTemplateSettings"][
            "uid"
        ].replace("v8", "v9")

    # Update lvConf
    if "lvConf" in project:
        # Remove v8 specific configurations (except LV_MEM_SIZE)
        v8_specific_keys = [
            key
            for key in project["lvConf"].keys()
            if (key.startswith("LV_MEM_") and key != "LV_MEM_SIZE")
            or key.startswith("LV_USE_GPU")
            or key.startswith("LV_FS_RAWFS_")
            or key.startswith("LV_COLOR_16_SWAP")
            or key.startswith("LV_ATTRIBUTE_")
        ]
        for key in v8_specific_keys:
            del project["lvConf"][key]

        # Add v9 specific configurations if needed
        project["lvConf"]["LV_USE_MEM_MONITOR"] = False
        project["lvConf"]["LV_USE_PERF_MONITOR"] = False
        project["lvConf"]["LV_GUIDER_SIMULATOR_WINDOW_ZOOM"] = 1

    # Update FrontJson elements
    if "FrontJson" in project:
        for screen in project["FrontJson"]:
            # Add missing properties to screen
            if "rm_flag" not in screen:
                screen["rm_flag"] = []

            if "list" in screen:
                for element in screen["list"]:
                    # Add missing properties to element
                    if "rm_flag" not in element:
                        element["rm_flag"] = []

                    # 如果元素类型为img，则删除dither_algorithm键值对
                    if element.get("type") == "img" and "dither_algorithm" in element:
                        del element["dither_algorithm"]
                    # 如果元素类型为img，则删除dither_algorithm键值对

                    if "style" in element:
                        for style in element["style"]:
                            # Convert v8 style properties to v9
                            # In v9, dithering is handled differently

                            # Add missing properties to style
                            style.setdefault("dither_algorithm", "")
                            style.setdefault("bg_img_storage", "")
                            if "color_format" in style:
                                style["color_format"] = "RGB565A8"

                            # Remove bg_dither_mode if present
                            if "bg_dither_mode" in style:
                                del style["bg_dither_mode"]

                            # 如果父元素类型为img，则删除style中的dither_algorithm
                            if element.get("type") == "img" and "dither_algorithm" in style:
                                del style["dither_algorithm"]

                            # Update font properties if needed
                            if "font" in style and isinstance(style["font"], int):
                                # In v9, font sizes might be handled differently
                                # Keeping the same value for now
                                pass

            # Update screen style properties
            if "style" in screen:
                for style in screen["style"]:
                    # For screen styles, don't add bg_dither_mode to match v9 reference
                    # Remove bg_dither_mode if present
                    if "bg_dither_mode" in style:
                        del style["bg_dither_mode"]

                    # Add missing properties to style
                    # style.setdefault("dither_algorithm", "")
                    # style.setdefault("bg_img_storage", "")
                    if "color_format" in style:
                        style["color_format"] = "RGB565A8"

    # 修改 FrontJson 中的 color_format
    if "FrontJson" in project:
        for item in project["FrontJson"]:
            if "list" in item:
                for sub_item in item["list"]:
                    if "color_format" in sub_item:
                        sub_item["color_format"] = "RGB565A8"
                    if "style" in sub_item:
                        for style_item in sub_item["style"]:
                            if "color_format" in style_item:
                                style_item["color_format"] = "RGB565A8"
            if "style" in item:
                for style_item in item["style"]:
                    if "color_format" in style_item:
                        style_item["color_format"] = "RGB565A8"
    
    # 修改 Application 中的 color_format
    if "Application" in project and "screen" in project["Application"]:
        for screen in project["Application"]["screen"]:
            if "style" in screen:
                for style_item in screen["style"]:
                    if "color_format" in style_item:
                        style_item["color_format"] = "RGB565A8"
            if "widgets" in screen:
                for widget in screen["widgets"]:
                    if "style" in widget:
                        for style_item in widget["style"]:
                            if "color_format" in style_item:
                                style_item["color_format"] = "RGB565A8"

    return project


def main():
    """Main function to handle command line arguments and execute the porting process."""
    if len(sys.argv) < 2:
        print(
            "Usage: python port_guiguider.py <input_file.guiguider> [output_file.guiguider]"
        )
        sys.exit(1)

    input_file = sys.argv[1]

    # Determine output file name
    if len(sys.argv) >= 3:
        output_file = sys.argv[2]
    else:
        base_name = os.path.splitext(input_file)[0]
        output_file = f"{base_name}_port.guiguider"

    # Determine reference file path
    script_dir = os.path.dirname(os.path.abspath(__file__))
    reference_file = os.path.join(script_dir, "lvgl_921.guiguider")

    # Execute the porting process
    port_project(input_file, output_file, reference_file)

    sort_json_cmd = f"sort_json.py {output_file}"
    result = os.system(sort_json_cmd)
    if result != 0:
        print(
            "Warning: Failed to execute sort_json.py. The output file may not be sorted."
        )
    # 使用sed命令将"true-color-alpha"替换为"RGB565A8"
    sed_cmd = f"sed -i 's/true-color-alpha/RGB565A8/g' {output_file}"
    result = os.system(sed_cmd)
    if result != 0:
        print("Warning: Failed to execute sed command. The output file may not be updated.")

if __name__ == "__main__":
    main()